package cfsmon.ui.console;

import java.io.IOException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Level;

import cfsmon.core.Configurator;

public class ConsoleInput {

	public static void parseCommandLine(String[] args, Configurator configurator){
		Options cmdlineOptions = new Options();
		setupOptions(cmdlineOptions);
		CommandLineParser parser = new PosixParser();
		try {
			CommandLine line = parser.parse(cmdlineOptions, args);
			handleOptions(line, cmdlineOptions, configurator);
			
		} catch (ParseException e) {
			configurator.abortConfig();
			e.printStackTrace();
		}
	}
	
	private static void handleOptions(CommandLine line, Options options, Configurator configurator){
		try{
			if (line.hasOption("h")){
				printHelp(options);
				configurator.abortConfig();
				return;
			}
			if (line.hasOption("v")){
				Level lvl = Level.toLevel(line.getOptionValue("v"), Level.ALL);
				configurator.setLoglevel(lvl);
			}
			if (line.hasOption("l")){
				configurator.setLogFile(line.getOptionValue("l"));
			}
			
			if (line.hasOption("i")){
				configurator.setInputFile(line.getOptionValue("i"));
			}
			
			if (line.hasOption("o")){
				configurator.setOutputFile(line.getOptionValue("o"));
			}
			
			if (line.hasOption("f")){
				configurator.forceOverwrite();
			}
			
			if (line.hasOption("s")){
				configurator.setNumberOfMonitorSlots(Integer.parseInt(line.getOptionValue("s")));
			}
			
			
		} catch (IOException e){
			printHelp(options);
			configurator.abortConfig();
		}
	}
	
	private static void printHelp(Options options){
		HelpFormatter formatter = new HelpFormatter();
		formatter.printHelp( "cfsmon [OPTIONS...]", options);
	}
	
	@SuppressWarnings("static-access")
	private static void setupOptions(Options options){
		options.addOption("h", "help", false, "print this message");
		
		options.addOption(
				OptionBuilder.withLongOpt("verbose")
							 .withArgName("file")
							 .hasArg()
							 .withDescription("set log4j verbose level " +
										"e.g. ALL (default), DEBUG, ERROR, INFO, OFF")
							 .create("v"));
		
		options.addOption(
				OptionBuilder.withLongOpt("logfile")
							 .withArgName("file")
							 .hasArg()
							 .withDescription("use given <file> for logging. Default is stdout.")
							 .create("l"));
		options.addOption(
				OptionBuilder.withLongOpt("inputfile")
							 .withArgName("file")
							 .hasArg()
							 .withDescription("read property input from <file>. Default is reading from stdin.")
							 .create("i"));
		options.addOption(
				OptionBuilder.withLongOpt("outputfile")
							 .withArgName("file")
							 .hasArg()
							 .withDescription("write generated header to <file>. Default is writing to stdout.")
							 .create("o"));
		
		options.addOption("f", "force-overwrite", false, "forces an output file to be overwritten.");
		
		options.addOption(
				OptionBuilder.withLongOpt("slots")
							 .withArgName("number")
							 .hasArg()
							 .withDescription("set the number of monitors maintained in paralell to <number>.")
							 .create("s"));
	}
	
}
